hvm: Align periodic vpts.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Feb 2009 09:43:06 +0000 (09:43 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 13 Feb 2009 09:43:06 +0000 (09:43 +0000)
Aligned periodic vpts can improve the HVM guest power consumption a
lot, especially while the guest using high HZ such as 1000HZ.

Signed-off-by: Wei Gang <gang.wei@intel.com>
tools/python/xen/xend/XendConfig.py
tools/python/xen/xend/XendConstants.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xm/create.py
tools/python/xen/xm/xenapi_create.py
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/vpt.c
xen/common/timer.c
xen/include/public/hvm/params.h
xen/include/xen/timer.h

index 4b30c1ae43504c90f316642533d364ecc093a13c..2d2138559bb235d557a36f4f07b335b4861a9b34 100644 (file)
@@ -158,6 +158,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
     'vncdisplay': int,
     'vnclisten': str,
     'timer_mode': int,
+    'vpt_align': int,
     'viridian': int,
     'vncpasswd': str,
     'vncunused': int,
@@ -459,6 +460,8 @@ class XendConfig(dict):
                 self['platform']['rtc_timeoffset'] = 0
             if 'hpet' not in self['platform']:
                 self['platform']['hpet'] = 0
+            if 'vpt_align' not in self['platform']:
+                self['platform']['vpt_align'] = 1
             if 'loader' not in self['platform']:
                 # Old configs may have hvmloader set as PV_kernel param
                 if self.has_key('PV_kernel') and self['PV_kernel'] != '':
index 13e046a0868c25532ce3cc858ca085e5852d7879..3130f75c08c985238fb5c64fe21eeb552c41b6bb 100644 (file)
@@ -50,6 +50,7 @@ HVM_PARAM_VIRIDIAN     = 9 # x86
 HVM_PARAM_TIMER_MODE   = 10
 HVM_PARAM_HPET_ENABLED = 11
 HVM_PARAM_ACPI_S_STATE = 14
+HVM_PARAM_VPT_ALIGN    = 16
 
 restart_modes = [
     "restart",
index 5c0899296363bf4f30643e8535d1db48ac1e710c..b56d3c55efd30fb0c8781eed1a291126ed77683a 100644 (file)
@@ -2237,6 +2237,12 @@ class XendDomainInfo:
             xc.hvm_set_param(self.domid, HVM_PARAM_HPET_ENABLED,
                              long(hpet))
 
+        # Optionally enable periodic vpt aligning
+        vpt_align = self.info["platform"].get("vpt_align")
+        if hvm and vpt_align is not None:
+            xc.hvm_set_param(self.domid, HVM_PARAM_VPT_ALIGN,
+                             long(vpt_align))
+
         # Set maximum number of vcpus in domain
         xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
 
index f87f5ccc53f9030b5e3ab4fc6dc76eb1ccd2b85c..d1a8ca2e0c3ab6410b6dac9629e2b3b126943c8c 100644 (file)
@@ -219,6 +219,10 @@ gopts.var('timer_mode', val='TIMER_MODE',
           use="""Timer mode (0=delay virtual time when ticks are missed;
           1=virtual time is always wallclock time.""")
 
+gopts.var('vpt_align', val='VPT_ALIGN',
+          fn=set_int, default=1,
+          use="Enable aligning all periodic vpt to reduce timer interrupts.")
+
 gopts.var('viridian', val='VIRIDIAN',
           fn=set_int, default=0,
           use="""Expose Viridian interface to x86 HVM guest?
@@ -891,7 +895,8 @@ def configure_hvm(config_image, vals):
              'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor',
              'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet',
              'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check',
-             'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate' ]
+             'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate',
+             'vpt_align' ]
 
     for a in args:
         if a in vals.__dict__ and vals.__dict__[a] is not None:
index 39489e497f20d162b57de16cbd2c56239f1c3d59..74a534f58c8757cae7d748549e7adc6334ae80fc 100644 (file)
@@ -1037,6 +1037,7 @@ class sxp2xml:
             'usbdevice',
             'hpet',
             'timer_mode',
+            'vpt_align',
             'viridian',
             'vhpt',
             'guest_os_type',
index ae4acb378704b3d358a66def3d16e2822979a435..517dbb33e88793f1718f666c29319a7273dd149c 100644 (file)
@@ -311,6 +311,7 @@ int hvm_domain_initialise(struct domain *d)
     hvm_init_guest_time(d);
 
     d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1;
+    d->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN]    = 1;
 
     hvm_init_cacheattr_region_list(d);
 
index 5dae7cd50593fc52f3063a2ca2b7a2e2862adf2d..33f2400a0eefe3066ac4e1233ab99fa022f9bf7c 100644 (file)
@@ -389,8 +389,14 @@ void create_periodic_time(
      * LAPIC ticks for process accounting can see long sequences of process
      * ticks incorrectly accounted to interrupt processing.
      */
-    if ( !pt->one_shot && (pt->source == PTSRC_lapic) )
-        pt->scheduled += delta >> 1;
+    if ( !pt->one_shot )
+    {
+        if ( v->domain->arch.hvm_domain.params[HVM_PARAM_VPT_ALIGN] )
+            pt->scheduled = align_timer(pt->scheduled, pt->period);
+        else if ( pt->source == PTSRC_lapic )
+            pt->scheduled += delta >> 1;
+    }
+
     pt->cb = cb;
     pt->priv = data;
 
index d5f08d370f207ac31142beccf999b3add4769272..eca25b3fb75664f0778daf7987fbf1dc97fa1509 100644 (file)
@@ -473,6 +473,13 @@ void process_pending_timers(void)
         timer_softirq_action();
 }
 
+s_time_t align_timer(s_time_t firsttick, uint64_t period)
+{
+    if ( !period )
+        return firsttick;
+
+    return firsttick + (period - 1) - ((firsttick - 1) % period);
+}
 
 static void dump_timerq(unsigned char key)
 {
index d5511bdd0a3a00ae914726c928279d0ea4f55216..15d828fe14dc1363101732cad034e27d1101d3b4 100644 (file)
 /* TSS used on Intel when CR0.PE=0. */
 #define HVM_PARAM_VM86_TSS     15
 
-#define HVM_NR_PARAMS          16
+/* Boolean: Enable aligning all periodic vpts to reduce interrupts */
+#define HVM_PARAM_VPT_ALIGN    16
+
+#define HVM_NR_PARAMS          17
 
 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
index f3d2705d82a1baf8c953e909c7f7655e85b778e6..0379d950a3f312f2039bf72f493753f7cf396598 100644 (file)
@@ -122,6 +122,9 @@ DECLARE_PER_CPU(s_time_t, timer_deadline);
 /* Arch-defined function to reprogram timer hardware for new deadline. */
 extern int reprogram_timer(s_time_t timeout);
 
+/* calculate the aligned first tick time for a given periodic timer */ 
+extern s_time_t align_timer(s_time_t firsttick, uint64_t period);
+
 #endif /* _TIMER_H_ */
 
 /*